package com.jec.module.sysmonitor.service;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;
import com.jec.Bootstrap;
import com.jec.base.entity.NetState;
import com.jec.module.business.service.BusinessService;
import com.jec.module.extern.Client_Service;
import com.jec.module.extern.NTNMS_ServiceImpl;
import com.jec.module.extern.ReportFault;
import com.jec.module.extern.ReportHeatbeat;
import com.jec.module.sysmanage.service.SysLogService;
import com.jec.module.sysmonitor.dao.CardRepository;
import com.jec.module.sysmonitor.dao.CardViewRepository;
import com.jec.module.sysmonitor.dao.NetConnectRepository;
import com.jec.module.sysmonitor.dao.NetUnitRepository;
import com.jec.module.sysmonitor.entity.Card;
import com.jec.module.sysmonitor.entity.CardState;
import com.jec.module.sysmonitor.entity.ConnectState;
import com.jec.module.sysmonitor.entity.NetConnect;
import com.jec.module.sysmonitor.entity.NetUnit;
import com.jec.module.sysmonitor.entity.NetUnitState;
import com.jec.module.sysmonitor.entity.view.CardView;
import com.jec.module.sysmonitor.vo.TopoState;
import com.jec.protocol.command.CommandExecutor;
import com.jec.protocol.command.PduCommand;
import com.jec.protocol.command.Result;
import com.jec.protocol.command.SlotCommand;
import com.jec.protocol.pdu.PDU;
import com.jec.protocol.pdu.PduConstants;
import com.jec.protocol.pdu.ProtocolUtils;
import com.jec.protocol.processor.Processor;
import com.jec.protocol.unit.BCD;

import lombok.extern.log4j.Log4j;

/**
 * Created by jeremyliu on 5/10/16.
 */
@Service
@Scope
@Log4j
public class NetWorkStateService extends Thread implements Processor{

	@Autowired
	private NetUnitRepository netUnitRepository;

	@Autowired
	private CardRepository cardRepository;

	@Autowired
	private CardViewRepository cardViewRepository;

	@Autowired
	private NetConnectRepository netConnectRepository;

	@Resource
	private NetWorkListenerService netWorkListenerService;

	@Resource
	private DeviceStateService deviceStateService;

	@Autowired
	private BusinessService businessService;
	
	@Autowired
	private SysLogService sysLogService;

	@Resource
	private Client_Service wsClient;

	private CommandExecutor ce = new CommandExecutor(false);
	
	private CommandExecutor register = new CommandExecutor(false);

	private ReadWriteLock lock = new ReentrantReadWriteLock();

	private Map<String, TopoState> states = new HashMap<>();

	private Map<Integer,Integer> netUnitStates = new HashMap<>();

	//private static List<NetUnit> netUnits = new ArrayList<>();
	
	private StateChangeHandler stateChangeHandler = new StateChangeHandler(); 
	
	private ConnectStateManager connectStateManager = new ConnectStateManager();
	
	private ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
	private List<String> diabledPorts = Lists.newLinkedList();
    @Autowired
    private NTNMS_ServiceImpl ntnmsService;

	@PostConstruct
	public void init(){
		
		netWorkListenerService.addProcessor(PduConstants.CMD_TYPE_SBJS,this);
		scheduler.scheduleWithFixedDelay(this, 2, 5, TimeUnit.SECONDS);
		
	}
	
	@PreDestroy
	public void exit(){
		//netWorkListenerService.addProcessor(PduConstants.CMD_TYPE_SBJS,this);
		scheduler.shutdown();
	}
	

	@Transactional(readOnly = true)
	public NetUnitState getInitState(int netUnitId){
		NetUnit netUnit =netUnitRepository.findOne(netUnitId);
		if(netUnit == null)
			return null;
		else
			return getInitState(netUnit);
	}
	
	private File getConfigFile() {
		
		String path = Bootstrap.getApplicationPath();
		
		String filename = path + File.separatorChar + "disabledports.txt";
		
		File configFile = new File(filename);
		
		return configFile;
	}

	@Transactional(readOnly = true)
	private NetUnitState getInitState(NetUnit netUnit){

		int netUnitId = netUnit.getId();
		NetUnitState state = new NetUnitState();
		Integer netUnitState = netUnitStates.get(netUnitId);
		if(netUnitState != null)
			state.setState(netUnitState);

		File configFile = getConfigFile();
		log.info("Loading: " + configFile.getAbsolutePath());
		if(configFile.exists() && configFile.isFile()) {
			try(FileReader fr = new FileReader(configFile)) {
				BufferedReader br = new BufferedReader(fr);
				String str;
				while ((str = br.readLine()) != null) {	
					String entry = str.trim();
					if(!entry.isEmpty())
						diabledPorts.add(entry);
				}
				br.close();
			} catch(Exception e) {
				log.warn("Load names failed.", e);
			}
		}
		/*
        Search search = new Search();
        search.addFilterEqual("netUnitId",netUnitId);
        search.addSort("slot",false);

        List<CardView> cards = cardViewDao.search(search);
		 */
		List<CardView> cards = cardViewRepository.findAllByNetUnitIdOrderBySlotAsc(netUnitId);
		int cardNumber = cards.size();

		CardState[] cardStates = new CardState[cardNumber];
		String path;

		lock.readLock().lock();
		for(int i=0; i<cardNumber; i++){
			path = TopoState.buildPath(netUnitId,i+1);
			CardView card = cards.get(i);
			cardStates[i] = new CardState();

			cardStates[i].setId(card.getId());

			if(states.containsKey(path)) {
				int slotState = states.get(path).getState();
				cardStates[i].setState(slotState);
				if(slotState == NetState.CS_FAILURE)
					state.setState(NetState.US_FAILURE);
			}

			int portNumber = card.getPortCount();
			if(portNumber > 0 && cardStates[i].getState() == 2) {
				NetState[] portStates = new NetState[portNumber];
				for(int j=0; j< portNumber; j++){
					portStates[j] = new NetState();
					portStates[j].setId(j);
					portStates[j].setState(NetState.CS_FAILURE);
				}
				cardStates[i].setPortState(portStates);
			}
			if(portNumber > 0 && cardStates[i].getState() != 2){
				NetState[] portStates = new NetState[portNumber];
				for(int j=0; j< portNumber; j++){
					portStates[j] = new NetState();
					portStates[j].setId(j);
					path = TopoState.buildPath(netUnitId,i+1,j);
					if(states.containsKey(path)) {
						int portState = states.get(path).getState();
						portStates[j].setState(portState);
//						if(portState == NetState.PS_FAILURE){
//							cardStates[i].setState(NetState.CS_FAILURE);
//							state.setState(NetState.US_FAILURE);
//						}
						if(diabledPorts.contains(TopoState.buildPath(netUnitId,i,j))) {
							portStates[j].setState(6);
						}
						if(portStates[j].getState() == NetState.CS_FAILURE) {
							cardStates[i].setState(NetState.CS_FAILURE);
							state.setState(NetState.US_FAILURE);
						}
					}
				}
				cardStates[i].setPortState(portStates);
			}
		}
		lock.readLock().unlock();
		state.setCardStates(cardStates);
		return state;
	}

	private int getNetUnitState(NetUnit netUnit){

		Result result = ce.open();
		if(!result.isSucceed()) {
			System.err.println(result.getDescription());
			return NetState.UNKNOWN;
		}
		String ip = netUnit.getIp();
		ce.setRemoteAddress(ip, netUnit.getPort());
		ce.setTimeout(2000);

		/*
        Search search = new Search();
        search.addFilterEqual("netUnitId", netUnit.getId());
        search.addFilterEqual("type", 1);
        List<Card> cards = cardDao.search(search);
		 */

		List<Card> cards = cardRepository.findAllByNetUnitIdAndType(netUnit.getId(), 1);
		if(cards.size() == 0)
			return NetState.UNKNOWN;

		//        int count = 0;
		//        int limit = 3;
		boolean force = true;

		PduCommand command = new PduCommand(netUnit.getNetId(),cards.get(0).getSlotNumber(), force);
		result = ce.execute(command);

		if(result.isSucceed()) {
			if(command.getResult())
				return NetState.US_NORMAL;
			else
				return NetState.US_OUTLINE;
		}else
			return NetState.US_OUTLINE;
	}
	
	public List<NetState> readNetunitState() {
		List<NetUnit> netUnits = netUnitRepository.findAll();
		List<NetState> state = new ArrayList<>(netUnits.size());

		//获取网元及设备的状态
		for(NetUnit netUnit : netUnits) {
			NetState netState = new NetState();
			netState.setId(netUnit.getId());
			if(netUnitStates.containsKey(netUnit.getId()))
				netState.setState(netUnitStates.get(netState.getId()));
			NetUnitState netUnitState = getInitState(netUnit.getId());
			if(netUnitState.getState() == NetState.US_FAILURE)
				netState.setState(NetState.US_FAILURE);
			state.add(netState);
		}
		return state;
	}
	
	public List<ConnectState> readConnectState() {
		
		//获取连接状态
		List<NetConnect> topos =  netConnectRepository.findAll();
		List<ConnectState> connectStates = new ArrayList<>();
		
		for(NetConnect topo : topos){

			int destId = topo.getDestId();
			ConnectState connectState = ConnectState.from(topo);
			Integer netState = netUnitStates.get(topo.getDestId());
			if(netState == null)
				netState = NetState.UNKNOWN;
			if(netState != NetState.US_NORMAL)
				connectState.setState(netState);
			else {
				String path = TopoState.buildPath(destId, topo.getSlot(), topo.getPort());
				lock.readLock().lock();
				if(states.containsKey(path))
					connectState.setState(states.get(path).getState());
				else
					connectState.setState(NetState.UNKNOWN);
				lock.readLock().unlock();
			}
			boolean find = false;
			for(ConnectState origin: connectStates){
				if(origin.getSrcId() == topo.getSrcId() && origin.getDestId() == topo.getDestId()){
					find = true;
					origin = connectState;
					break;
				}
			}
			if(!find)
				connectStates.add(connectState);
		}
		
		return connectStates;
	}
	
	@Transactional(readOnly = true)
	public Map<String, Object> readAllState(){
		Map<String,Object> map = new HashMap<>();
		map.put("netunit", readNetunitState());
		map.put("connect", readConnectState());
		map.put("device", deviceStateService.queryDevice());
		return map;
	}

	@Transactional(readOnly = true)
	public int faultNetunitCount() {

		int count = 0;

		//获取网元及设备的状态
		List<NetUnit> netUnits = netUnitRepository.findAll();
		for(NetUnit netUnit : netUnits) {
			
			Integer state = netUnitStates.get(netUnit.getId());
			
			if(state == null) state = NetState.UNKNOWN;
			
			if(state != NetState.US_NORMAL)
				count++;

		}
		/*
		//获取连接状态
		List<NetConnect> topos =  netConnectRepository.findAll();
		List<ConnectState> connectStates = new ArrayList<>(netUnits.size());
		for(NetUnit src: netUnits){
			for( NetUnit dest: netUnits)
				if(src != dest) {
					ConnectState connectState = new ConnectState();
					connectState.setSrcId(src.getId());
					connectState.setDestId(dest.getId());
					connectStates.add(connectState);
				}
		}
		
		
		for(NetConnect topo : topos){

			int destId = topo.getDestId();
			ConnectState connectState = ConnectState.from(topo);
			Integer netState = netUnitStates.get(topo.getSrcId());
			if(netState == null)
				netState = NetState.UNKNOWN;
			
			if(netState != NetState.US_NORMAL)
				connectState.setState(netState);
			else {
				String path = TopoState.buildPath(destId, topo.getSlot(), topo.getPort());
				lock.readLock().lock();
				if(states.containsKey(path))
					connectState.setState(states.get(path).getState());
				else
					connectState.setState(NetState.UNKNOWN);
				lock.readLock().unlock();
			}
			boolean find = false;
			for(ConnectState origin: connectStates){
				if(origin.getSrcId() == topo.getSrcId() && origin.getDestId() == topo.getDestId()){
					find = true;
					origin = connectState;
					break;
				}
			}
			if(!find)
				connectStates.add(connectState);
		}
		*/

		return count;
	}


	@Transactional(readOnly = true)
	public void refreshCardState(NetUnit netUnit){
		CommandExecutor ce = new CommandExecutor();

		SlotCommand slotCommand = new SlotCommand(0,0,0,0);
		ce.setRemoteAddress(netUnit.getIp(), netUnit.getPort());


		int mainSlot = -1;

		List<Card> cards = cardRepository.findAllByNetUnitIdAndTypeNot(netUnit.getId(), PduConstants.CARD_TYPE_NUL);
		for(Card card : cards){
			if(card.getType() == PduConstants.CARD_TYPE_MCB){
				mainSlot = card.getSlotNumber();
				break;
			}
		}
		slotCommand.setNetunit(netUnit.getNetId(),mainSlot);
		for(Card card : cards){
			slotCommand.setSlot(card.getSlotNumber(), card.getType());
			ce.execute(slotCommand);
			try{
				Thread.sleep(50);
			}catch (InterruptedException e){
				e.printStackTrace();
			}
		}

	}

	public boolean isOnline(int netUnit){
		Integer state = netUnitStates.get(netUnit);
		if(state == null) return false;
		return  state== NetState.US_NORMAL || state ==NetState.US_FAILURE;
	}

	private boolean isStateOnline(Integer state){
		return  state!=null &&
				(state== NetState.US_NORMAL ||
				state ==NetState.US_FAILURE);
	}

	@Transactional(readOnly = true)
	private  void setCardState(int netUnitId, int slot, int state){

		NetUnit netUnit = netUnitRepository.findOneByNetId(netUnitId);
		if(netUnit == null)
			return;

		state = NetState.cardStateMap(state);
		String path = TopoState.buildPath(netUnit.getId(),slot);
		lock.writeLock().lock();
		if(states.containsKey(path)){
			TopoState s = states.get(path);
			stateChangeHandler.onCard(netUnitId, slot, s.getState(), state);
			s.setState(state);
		}else {
			states.put(path,new TopoState(netUnit.getId(), slot,state));
			stateChangeHandler.onCard(netUnitId, slot, null, state);
		}
		lock.writeLock().unlock();
	}

	@Transactional(readOnly = true)
	private void setPortState(int netUnitId, int slot, int port, int state){
		NetUnit netUnit = netUnitRepository.findOneByNetId(netUnitId);
		if(netUnit == null)
			return;

		state = NetState.portStateMap(state);
		String path = TopoState.buildPath(netUnit.getId() ,slot, port);
		lock.writeLock().lock();
		if(states.containsKey(path)){
			TopoState s = states.get(path);
			stateChangeHandler.onPort(netUnitId, slot, port, s.getState(), state);
			s.setState(state);
		}else {
			stateChangeHandler.onPort(netUnitId, slot, port, null, state);
			states.put(path,new TopoState(netUnit.getId(), slot, port, state));
		}
		lock.writeLock().unlock();
	}

	@Override
	public boolean process(PDU pdu) {

		int type = ProtocolUtils.getCmdConfig(pdu);

		int offset = PduConstants.LENGTH_OF_HEAD;

		int netunit = ProtocolUtils.getSourId(pdu);


		if(type == PduConstants.MONITOR_NET_CARD) {
			offset++;//int type = pdu.getInt8(offset++);
			int slot = pdu.getInt8(offset);
			offset++;
			int state = pdu.getInt8(offset);
			setCardState(netunit, slot, state);
			/*
			if(state == 1)
			{

				ReportFault builder = new ReportFault();
				builder.add(
						Integer.toString(netunit), 
						"2", //faultLevel, 
						"1", //faultType, 
						"20002014", //faultCode, 
						"网络错误");//faultDesp

				wsClient.feed(builder.build());
				//zhwgWs.reportRemoteRequest(faultMsg);   
				
				sysLogService.addLog(0, "0-0", "板卡故障，网元：" + netunit + " 槽位：" + slot);
			}*/
			return true;

		}else if( type == PduConstants.MONITOR_NET_PORT){
			offset++;//int type = pdu.getInt8(offset++);
			int slot = pdu.getInt8(offset);
			offset++;
			int port = pdu.getInt8(offset);
			offset++;
			int state = pdu.getInt8(offset);
			setPortState(netunit, slot, port, state);
			/*
			if(state == 1)
			{

				ReportFault builder = new ReportFault();
				builder.add(
						Integer.toString(netunit), 
						"2", //faultLevel, 
						"2", //faultType, 
						"20002014", //faultCode, 
						"网络错误");//faultDesp

				wsClient.feed(builder.build());
				//zhwgWs.reportRemoteRequest(faultMsg);  
				
				sysLogService.addLog(0, "0-0", "端口故障，网元：" + netunit + " 槽位：" + slot + " 端口" + port);
			}
			*/
			return true;
		}else if (type == PduConstants.MONITOR_NET_DEVICE){
			BCD number = pdu.getBCD(offset, PduConstants.LENGTH_OF_BCD);
			offset += PduConstants.LENGTH_OF_BCD;

			int stateCode = pdu.getInt8(offset);
			
			stateChangeHandler.onDevice(netunit, number, deviceStateService.getDeviceState(number.toString()), NetState.deviceStateMap(stateCode));
			
			deviceStateService.setDeviceState(number.toString(), stateCode);
			
			log.info("MONITOR_NET_DEVICE -> device:"+number.toString()+",state:"+stateCode);
			
			return true;
		}
		else
			return false;      
	}

	@Override
    public void run(){ 
		
		try {

			//ReportHeatbeat builder = new ReportHeatbeat();

			//获取网元及设备的状态
			List<NetUnit> netUnits = netUnitRepository.findAll(); 			
			for(NetUnit netUnit : netUnits) {

				int netUnitState = getNetUnitState(netUnit);                 

				/*
				if(netUnitState ==NetState.US_NORMAL)
					builder.add(Integer.toString(netUnit.getId()), "0");
				else if(netUnitState ==NetState.UNKNOWN)
					builder.add(Integer.toString(netUnit.getId()), "2");
				else //网络故障
					builder.add(Integer.toString(netUnit.getId()), "1");
				*/

				int netUnitId = netUnit.getId();
				Integer curState = netUnitStates.get(netUnitId);
				
				// 调试用，强制网元正常状态
				//netUnitState = NetState.US_NORMAL;
				// 
				stateChangeHandler.onNetunit(netUnitId, curState, netUnitState);
				
				if( (netUnitState == NetState.US_NORMAL || netUnitState == NetState.US_FAILURE)
						&& (curState == null || curState == NetState.US_OUTLINE
						|| curState == NetState.UNKNOWN)){

					refreshCardState(netUnit);
					deviceStateService.refreshState(netUnit);
				}
				
				// 设置网元状态
				netUnitStates.put(netUnitId, netUnitState);
				
				// 如果状态从在线变为非在线，清除业务状态和设备状态
				if(isStateOnline(curState) && !isStateOnline(netUnitState)) {
					businessService.clearData(netUnitId);
					deviceStateService.clearState(netUnitId);
				}
			}

			/*发送 心跳请求*/
			//wsClient.feed(builder.build());
			
		} catch (Throwable ie){
			log.error("NetworkStateService schedule error", ie);
		} 

	}
	
	@Scheduled(cron="0 0/1 *  * * ? ")  
	public void report() {
		
		ReportHeatbeat builder = new ReportHeatbeat();
		
		//获取网元及设备的状态
		List<NetUnit> netUnits = netUnitRepository.findAll(); 			
		for(NetUnit netUnit : netUnits) {
			
			Integer state = netUnitStates.get(netUnit.getId());
			
			if(state == null) state = NetState.UNKNOWN;
			
			if(state == NetState.US_NORMAL)
				builder.add(Integer.toString(netUnit.getId()), "0");
			else if(state == NetState.UNKNOWN)
				builder.add(Integer.toString(netUnit.getId()), "2");
			else //网络故障
				builder.add(Integer.toString(netUnit.getId()), "1");
		}
		
		/*发送 心跳请求*/
		wsClient.feed(builder.build());
		
		log.info("report");
		
	}
	
	@Scheduled(cron="0/5 * *  * * ? ")  
	public void schedule() {
		connectStateManager.merge(readConnectState());
	}
	
	@Scheduled(cron="0/5 * *  * * ? ")  
	public void scheduleRegister() {
		
		try {

			//获取网元及设备的状态
			List<NetUnit> netUnits = netUnitRepository.findAll(); 			
			for(NetUnit netUnit : netUnits) {
				
				
				Result result = register.open();
				if(!result.isSucceed()) {
					log.warn(result.getDescription());
					continue;
				}
				
				String ip = netUnit.getIp();
				ce.setRemoteAddress(ip, netUnit.getPort());
				ce.setTimeout(2000);

				List<Card> cards = cardRepository.findAllByNetUnitIdAndType(netUnit.getId(), 1);
				if(cards.size() == 0) {
					log.warn("No MCB on Netunit: " + netUnit.getName());
					continue;
				}

				boolean force = true;

				PduCommand command = new PduCommand(netUnit.getNetId(),cards.get(0).getSlotNumber(), force);
				command.setNeedResponse(false);
				register.execute(command);

			}
						
		} catch (Throwable ie){
			log.error("NetworkStateService register schedule failed.", ie);
		} 
	}

	@Transactional(readOnly = true)
	public void refreshAll(){
		List<NetUnit> netUnits = netUnitRepository.findAll();
		//获取网元及设备的状态
		for(NetUnit netUnit : netUnits) {
			if(isOnline(netUnit.getId())) {
				refreshCardState(netUnit);
				deviceStateService.refreshState(netUnit);
			}
		}
	}

	@Transactional(readOnly = true)
	public boolean refresh(int netunit){
		NetUnit netUnit = netUnitRepository.findOne(netunit);
		if(netUnit == null)
			return false;
		refreshCardState(netUnit);
		deviceStateService.refreshState(netUnit);
		return true;
	}
	
	class ConnectStateManager {
		
		private List<ConnectState> states = Lists.newLinkedList();
		
		public void merge(List<ConnectState> newStates) {
						
			for(ConnectState s : newStates) {
				
				ConnectState origin = stateByState(s);
				
				stateChangeHandler.onConnect(origin, s);
				
				origin.setState(s.getState());
								
			}
			
		}
		
		private ConnectState stateByState(ConnectState state) {
			
			for(ConnectState s : states) {
				if(isEqual(s, state)) 
					return s;
			}
			
			ConnectState s = ConnectState.from(state);	
			states.add(s);
			return s;
			
		}
		
		boolean isEqual(ConnectState s1, ConnectState s2) {
			return s1.getSrcId() == s2.getSrcId() && s1.getDestId() == s2.getDestId();
		}
		
	}
	
	class StateChangeHandler {
		
		public void onConnect(ConnectState oldState, ConnectState newState) {
			
			if(oldState.getState() != newState.getState()) {
				
				if(newState.getState() != NetState.US_OUTLINE && newState.getState() != NetState.US_NORMAL ) {
					
					String sourceName = Integer.toString(oldState.getSrcId());
					String targetName = Integer.toString(oldState.getDestId());
					
					NetUnit netunit = netUnitRepository.findOneByNetId(oldState.getSrcId());
					if(netunit != null) {
						sourceName = netunit.getName();
					}
					
					netunit = netUnitRepository.findOneByNetId(oldState.getDestId());
					if(netunit != null) {
						targetName = netunit.getName();
					}
					
					String faultDesp = "内通接入设备" + sourceName + "到" + targetName + "光纤链路故障";
					
					/*发送 故障上班请求*/
					ReportFault builder2 = new ReportFault();
					builder2.add(
							Integer.toString(oldState.getDestId()), 
							"2", //faultLevel, 
							"2", //faultType, 
							"3611", //faultCode, 
							faultDesp);//faultDesp
					wsClient.feed(builder2.build());
					
					sysLogService.addLog(0, "0-0", faultDesp);					
					
				}
				
				ntnmsService.topoQuery();
				
			}
			
			
		}
		
		
		public void onNetunit(int netunit, Integer oldState, int newState) {
			
			if(oldState != null && !oldState.equals(newState)) {
				
				if(newState != NetState.UNKNOWN && newState != NetState.US_NORMAL) {
				
					/*发送 故障上班请求*/
					
					String name = Integer.toString(netunit);
					NetUnit nu = netUnitRepository.findOne(netunit);
					if(nu != null) {
						name = nu.getName();
					}
					
					String faultDesp = "内通接入设备" + name + "通信故障";
					
					
					ReportFault builder2 = new ReportFault();
					builder2.add(
							Integer.toString(netunit), 
							"2", //faultLevel, 
							"2", //faultType, 
							"3621", //faultCode, 
							faultDesp);//faultDesp
					wsClient.feed(builder2.build());
					
					
					sysLogService.addLog(0, "0-0", "网元故障，网元：" + netunit);
				
				}
				
			}
	
		}
		
		public void onCard(int netunit, int slot, Integer oldState, int newState) {
			
			if(oldState != null && !oldState.equals(newState)) {
				
				//
				if(newState == NetState.US_FAILURE) {
					
					/*
					ReportFault builder = new ReportFault();
					builder.add(
							Integer.toString(netunit), 
							"2", //faultLevel, 
							"1", //faultType, 
							"20002014", //faultCode, 
							"板卡故障");//faultDesp

					wsClient.feed(builder.build());
					*/ 
					
					sysLogService.addLog(0, "0-0", "板卡故障，网元：" + netunit + " 槽位：" + slot);
					
				}
				
			}
			
			
		}
		
		public void onPort(int netunit, int slot, int port, Integer oldState, int newState) {
			
			if(oldState != null && !oldState.equals(newState)) {
				
				// 
				if(newState == NetState.US_FAILURE) {
					
					/*
					ReportFault builder = new ReportFault();
					builder.add(
							Integer.toString(netunit), 
							"2", //faultLevel, 
							"2", //faultType, 
							"20002014", //faultCode, 
							"端口故障");//faultDesp

					wsClient.feed(builder.build());
					*/
					
					sysLogService.addLog(0, "0-0", "端口故障，网元：" + netunit + " 槽位：" + slot + " 端口" + port);
					
				}
				
				
				
			}
			
			
		}

		public void onDevice(int netunit, BCD number, Integer oldState, int newState) {

			
			if(oldState != null && !oldState.equals(newState)) {
				
				// 
				if(newState == NetState.US_FAILURE) {
					
					/*
					ReportFault builder = new ReportFault();
					builder.add(
							Integer.toString(netunit), 
							"2", //faultLevel, 
							"2", //faultType, 
							"2201", //faultCode, 
							"终端设备链路故障");//faultDesp

					wsClient.feed(builder.build());
					*/
					sysLogService.addLog(0, "0-2", "设备故障，网元：" + netunit + " 号码：" + number.toString());					
				}

			}
			
			
		}
		

		
		
		
		
		
		
	}
	
	
}
